﻿using System;
using System.Text;
using System.Windows.Threading;
namespace DispatcherCore
{
    /// <summary>
    /// UI线程对象
    /// </summary>
    public static class DispatcherCore
	{
		public static Dispatcher UIDispatcher { get; private set; }

		#region private

		private static void CheckBeginInvokeOnUI(Action action)
		{
			if (action == null)
			{
				return;
			}
			CheckDispatcher();
			if (UIDispatcher.CheckAccess())
			{
				action();
				return;
			}
			UIDispatcher.Invoke(action, new object[0]);
		}

		private static void CheckDispatcher()
		{
			if (UIDispatcher == null)
			{
				StringBuilder stringBuilder = new StringBuilder("The DispatcherCore is not initialized.");
				stringBuilder.AppendLine();
				stringBuilder.Append("Call DispatcherCore.Initialize() in the static App constructor.");
				throw new InvalidOperationException(stringBuilder.ToString());
			}
		}

		private static DispatcherOperation RunAsync(Action action)
		{
			CheckDispatcher();
			return UIDispatcher.BeginInvoke(action, new object[0]);
		}
		#endregion

		/// <summary>
		/// 初始化UI线程，在UI主线程中调用
		/// </summary>
		public static void Initialize()
		{
			if (UIDispatcher != null && UIDispatcher.Thread.IsAlive)
			{
				return;
			}
			UIDispatcher = Dispatcher.CurrentDispatcher;
		}

		public static void Reset()
		{
			UIDispatcher = null;
		}



		/// <summary>
		/// 在UI线程执行委托
		/// </summary>
		/// <param name="func"></param>
		/// <param name="action">错误回调</param>
		public static void RunInUI(Action func, Action<Exception> action = null)
		{
			DispatcherCore.CheckBeginInvokeOnUI(() =>
			{
				try
				{
					func();
				}
				catch (Exception ex)
				{
					if (action != null)
					{ action(ex); }
				}
			});
		}
		/// <summary>
		/// 在UI线程异步执行委托
		/// </summary>
		/// <param name="func"></param>
		public static DispatcherOperation AsyncRunInUI(Action func)
		{
			return RunAsync(func);
		}
		/// <summary>
		///异步委托
		/// </summary>
		/// <param name="func"></param>
		public static void AsyncRun(Action func)
		{
			func.BeginInvoke((ar) =>
			{
				func.EndInvoke(ar);
			},
			null);
		}
		/// <summary>
		///异步委托
		/// </summary>
		/// <param name="func"></param>
		public static void AsyncRun(Func<object> func, Action<object> callBackAction)
		{

			func.BeginInvoke((ar) =>
			{
				var result = func.EndInvoke(ar);
				callBackAction.Invoke(result);
			},
			null);
		}
		
	}
}
